package com.example.securityconfiggen.service;

import com.dragonpass.global.common.lite.security.util.SecurityUtil;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import static com.dragonpass.global.common.lite.security.constants.SecurityConstants.ENCRYPT_KEY;
import static com.dragonpass.global.common.lite.security.constants.SecurityConstants.SECRET_KEY;

@Service
public class YamlService {

    /**
     * 处理YAML内容，同时返回MD5和Base64两种加密结果
     * 
     * @param projectName 项目名称
     * @param yamlContent YAML格式的内容
     * @return 包含两种加密结果的Map
     */
    public Map<String, String> processYaml(String projectName, String yamlContent) {
        try {
            // 创建敏感配置的properties对象
            Properties securityProps = new Properties();
            // 创建keyvault配置的properties对象
            Properties keyVaultProps = new Properties();
            
            // 使用Yaml解析器解析YAML内容
            Yaml yaml = new Yaml();
            Map<String, Object> yamlMap = yaml.load(yamlContent);
            
            // 处理YAML内容
            processYamlMap(yamlMap, "", securityProps, keyVaultProps, projectName);
            
            // 将Properties转换为YAML格式
            Map<String, Object> securityYamlMap = new LinkedHashMap<>();
            for (String key : securityProps.stringPropertyNames()) {
                String value = securityProps.getProperty(key);
                addToYamlMap(securityYamlMap, key, value);
            }
            
            // 配置YAML输出选项
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
            options.setPrettyFlow(true);
            Yaml yamlDumper = new Yaml(options);
            
            // 生成YAML格式的本地敏感配置
            StringBuilder md5Result = new StringBuilder();
            md5Result.append("# ").append(projectName).append(" - 项目本地配置结果\n");
            md5Result.append(yamlDumper.dump(securityYamlMap));

            // 生成Properties格式的keyvault配置
            StringBuilder base64Result = new StringBuilder();
            base64Result.append("# ").append(projectName).append(" - Keyvault配置结果\n");
            for (String key : keyVaultProps.stringPropertyNames()) {
                base64Result.append(key).append("=").append(keyVaultProps.getProperty(key)).append("\n");
            }
            
            // 生成KeyVault执行命令
            StringBuilder keyvaultCommands = new StringBuilder();
            keyvaultCommands.append("# ").append(projectName).append(" - KeyVault执行命令\n");
            for (String key : keyVaultProps.stringPropertyNames()) {
                String value = keyVaultProps.getProperty(key);
                keyvaultCommands.append("az keyvault secret set --vault-name YOUR-VAULT-NAME --name ").append(key).append(" --value \"").append(value).append("\"\n");
            }

            // 返回包含两种加密结果的Map
            Map<String, String> results = new HashMap<>();
            results.put("md5", md5Result.toString());
            results.put("base64", base64Result.toString());
            results.put("keyvaultCommands", keyvaultCommands.toString());
            return results;
            
        } catch (Exception e) {
            throw new RuntimeException("处理YAML内容时出错: " + e.getMessage(), e);
        }
    }
    
    /**
     * 将键值对添加到YAML Map中
     * 
     * @param yamlMap YAML Map
     * @param key 键
     * @param value 值
     */
    private void addToYamlMap(Map<String, Object> yamlMap, String key, String value) {
        String[] parts = key.split("\\.");
        Map<String, Object> currentMap = yamlMap;
        
        for (int i = 0; i < parts.length - 1; i++) {
            String part = parts[i];
            if (!currentMap.containsKey(part)) {
                currentMap.put(part, new LinkedHashMap<String, Object>());
            }
            currentMap = (Map<String, Object>) currentMap.get(part);
        }
        
        currentMap.put(parts[parts.length - 1], value);
    }
    
    /**
     * 递归处理YAML Map
     * 
     * @param yamlMap YAML解析后的Map
     * @param prefix 键前缀
     * @param securityProps 敏感配置属性
     * @param keyVaultProps KeyVault配置属性
     * @param projectName 项目名称
     */
    @SuppressWarnings("unchecked")
    private void processYamlMap(Map<String, Object> yamlMap, String prefix, Properties securityProps, Properties keyVaultProps, String projectName) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, NoSuchAlgorithmException, BadPaddingException, InvalidKeySpecException, InvalidKeyException {
        for (Map.Entry<String, Object> entry : yamlMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            String fullKey = prefix.isEmpty() ? key : prefix + "." + key;
            
            if (value instanceof Map) {
                // 继续递归处理子节点
                processYamlMap((Map<String, Object>) value, fullKey, securityProps, keyVaultProps, projectName);
            } else if (value != null) {
                // 叶子节点，处理值
                processProperty(fullKey, value.toString(), securityProps, keyVaultProps, projectName);
            }
        }
    }
    
    /**
     * 处理属性值
     * 
     * @param key 属性键
     * @param value 属性值
     * @param securityProps 敏感配置属性
     * @param keyVaultProps KeyVault配置属性
     * @param projectName 项目名称
     */
    private void processProperty(String key, String value, Properties securityProps, Properties keyVaultProps, String projectName) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, NoSuchAlgorithmException, BadPaddingException, InvalidKeySpecException, InvalidKeyException {
        String concatStr = key.replaceAll("\\.", "-").replaceAll("_", "-");
        String key1 = projectName.concat("-").concat(concatStr).concat("-").concat(SECRET_KEY);
        String key2 = projectName.concat("-").concat(concatStr).concat("-").concat(ENCRYPT_KEY);
        
        securityProps.setProperty("dragonpass.security.keyvault.".concat(key).concat(".").concat(SECRET_KEY), key1);
        securityProps.setProperty("dragonpass.security.keyvault.".concat(key).concat(".").concat(ENCRYPT_KEY), key2);

        String k = SecurityUtil.generateSecret();
        keyVaultProps.setProperty(key1, k);
        keyVaultProps.setProperty(key2, SecurityUtil.encrypt(value, k));
    }
} 